<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>

        // ++++++++++++++++++++++++++++ let 
        // var a = 2;
        // let b = 2;
        // {
        //     var a = 3;
        //     let b = 3;
        // }
        // console.log(a);
        // console.log(b);

        // ++++++++++++++++++++++++++++ const 
        // {
        //     const ARR = [5,6];
        //     ARR.push(7);
        //     console.log(ARR);
        //     ARR = 10; // TypeError
        // }

        // ++++++++++++++++++++++++++++ arrow
        // function Person(){
        //     this.age = 0;
            
        //     setInterval(() => {
        //         //this指向当前词法作用域Person方法内
        //         this.age++;
        //     }, 1000);
        // }
        // var person = new Person();
        // console.log(person);

        // ++++++++++++++++++++++++++++ spread和rest
        // // 用于迭代传实参时是spread操作符
        // let arr = [1,2,3];
        // function funcSpread(x,y,z){
        //     return x+y+z;
        // }
        // let result = funcSpread(...arr);//[1,2,3] => 1,2,3
        // console.log(result);

        // //用于函数定义接收参数时是rest操作符
        // function funcRest(...arr){//1,2,3 => [1,2,3] 
        //     console.log(arr); 
        // }
        // funcRest(1,2,3);

        // ++++++++++++++++++++++++++++ 对象词法拓展，简写语法
        // function Obj(a,b,c){
        //     //在方法定义对象中简写前return
        //     return {
        //         //变量声明简写
        //         a,b,c,
        //         //变量可以用表达式表示
        //         ['A'+ a + "A"]: "双A护体",
        //         //方法省略function
        //         func(){
        //             return this.b + this.c;
        //         }
        //     }
        // }
        // let obj = new Obj(1,2,3)
        // console.log(obj);
        // console.log(obj.func());

        // ++++++++++++++++++++++++++++ 二进制和八进制字面量
        // console.log("八进制：",0o10); //前面加0o
        // console.log("二进制：",0b10); //前面加0b
        // console.log("十进制：",10);

        // ++++++++++++++++++++++++++++ 数组和对象解构
        // //数组
        // function func(){
        //     return [1,2,3];
        // }
        // console.log(func());
        // let [x,y,z] = func();
        // console.log(x,y,z);

        // // 对象
        // function obj(){
        //     return {
        //         x:1,y:2,z:3,k:4
        //     }
        // }
        // let {x,y,z:z} = obj();
        // console.log(x,y,z);

        // ++++++++++++++++++++++++++++ 数组和对象解构
        // let parent = {
        //     func(){
        //         console.log("this is parent");
        //     }
        // }
        // let child = {
        //     func(){
        //         super.func();
        //         console.log("this is child");
        //     }
        // }
        // Object.setPrototypeOf(child, parent);
        // parent.func();
        // console.log("up is parent and down is child");
        // child.func();

        // ++++++++++++++++++++++++++++ 模板语法和符号
        // let name = "jim";
        // let introduce = `
        //     <p style="color:red">
        //         ${name}    
        //     </p>
        // `
        // document.write(introduce);

        // ++++++++++++++++++++++++++++ for of 和for in
        // let arr = ["a","b","c"];
        // for(let v of arr){ // 遍历数组值，对象不可遍历
        //     console.log(v+v);
        // }
        // let obj = {
        //     a:"apple",
        //     b:"block",
        //     c:"class"
        // }
        // for(let k in arr){ // 遍历数组或对象的属性名
        //     console.log(arr[k]);
        // }
        // for(let k in obj){
        //     console.log(obj[k]);  //此处遍历对象，只能[k]，不可.k
        // }
        // console.log("bbb:",obj.b)

        // ++++++++++++++++++++++++++++ Map 和WeakMap
        // // Map
        // let map = new Map();
        // map.set(f = function func(){}, "this is a function");
        // map.set("h","this is a string");
        // map.set(arr = [1,2,3],"this is a arr");
        // console.log(map.get(f));
        // console.log(map.get("h"));
        // console.log(map.get(arr));

        // // WeakMap 
        // // 所有key都必须是对象，弱引用，即变量中的数据垃圾回收时不会考虑，所以用它不用担心内存泄漏
        // let weakMap = new WeakMap();
        // let f1 = 1;
        // weakMap.set(f1 = function(){}, "this is a function");
        // console.log(weakMap.get(f1));
        // console.log(weakMap.has(f1));
        // weakMap.delete(f1);
        // console.log(weakMap.has(f1));

        // ++++++++++++++++++++++++++++ Set 和 WeakSet
        // // Set
        // let mySet = new Set([1, 1, 2, 2, 3, 3]);
        // console.log(mySet);
        // console.log(mySet.size);
        // console.log(mySet.has(2));
        // mySet.add('strings');
        // mySet.add({ a: 1, b:2 });
        // console.log(mySet);
        // for(let val of mySet){  //用for of遍历
        //     console.log(val);
        // }
        // mySet.forEach((item) => {  //用forEach遍历
        //     console.log(item);
        // })
        // mySet.delete(2); //删除单个元素
        // console.log(mySet.has(2));
        // mySet.clear(); //清空元素
        // console.log(mySet);

        // // WeakSet 
        // 所有key都必须是对象，弱引用，即变量中的数据垃圾回收时不会考虑，所以用它不用担心内存泄漏
        // let weakSet = new WeakSet();
        // let f1 = 1;
        // weakSet.add(f1 = function(){}, "this is a function");
        // console.log(weakSet.has(f1));
        // weakSet.delete(f1);
        // console.log(weakSet.has(f1));

        // ++++++++++++++++++++++++++++ class
        // class Task {
        //     constructor() {
        //         console.log("task instantiated!");
        //     }
            
        //     showId() {
        //         console.log(22);
        //     }
            
        //     static loadAll() {
        //         console.log("Loading all tasks..");
        //     }
        // }
        // console.log(typeof Task);  //类型为function class定义方式只是function定义方式的语法糖
        // class ExpandTask extends Task{
        //     constructor() {
        //         super();
        //         console.log("expandTask instantiated!");
        //     }
            
        //     static loadAll() {
        //         console.log("Loading all expandTasks..");
        //     }
        // }
        // let expandtask = new ExpandTask();
        // expandtask.showId();
        // ExpandTask.loadAll();

        // ++++++++++++++++++++++++++++ Symbol
        // let sym = Symbol("a symbol");
        // console.log(sym);
        // console.log(typeof sym);
        // let obj = {
        //     sym: Symbol("a symbol"),
        //     [ Symbol("a symbol") ]: "I'm a symbol",
        // };
        // console.log(obj.sym);
        // console.log(Object.getOwnPropertyNames(obj));
        // console.log(Object.getOwnPropertySymbols(obj)); //symbol作为属性名需要用该方法获得属性名

        // ++++++++++++++++++++++++++++ Iterators
        // let arr = [1,2,"a",4,5];
        // let itr = arr[Symbol.iterator]();
        // console.log(itr.next());
        // console.log(itr.next());
        // console.log(itr.next());
        // console.log(itr.next());
        // console.log(itr.next());
        // console.log(itr.next());

        // ++++++++++++++++++++++++++++ Generators
        // function *infiniteNumbers() {  //加*方法可返回迭代器
        //     var n = 1;
        //     while (true){
        //         yield n++;   // yield给迭代器卡点
        //     }
        // }
        // let numbers = infiniteNumbers(); 
        // console.log(numbers.next());
        // console.log(numbers.next());
        // console.log(numbers.next());
        // console.log(numbers.next());
        // console.log(numbers.next());
        // console.log(numbers.next());

        // ++++++++++++++++++++++++++++ Promise
        // let number = 15;
        // var p = new Promise(function(resolve, reject) {  
        //     if (number>10) {
        //         resolve("number大于10，成功！");
        //     } else {
        //         reject("number小于10，失败！");  
        //     }
        // });
        // p.then(
        //     //第一个参数处理成功
        //     (val)=>{
        //         console.log(val);
        //     },
        //     //第二个参数处理失败
        //     (err)=>{
        //         console.log(err);
        //     }
        // )
 
        

    </script>
</body>
</html>